package com.lifesting.tool.encoding.properties;

import com.lifesting.tool.encoding.Activator;
import com.lifesting.tool.encoding.Setting;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IPath;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.CheckboxCellEditor;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.ColumnViewer;
import org.eclipse.jface.viewers.ComboBoxCellEditor;
import org.eclipse.jface.viewers.EditingSupport;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.viewers.TextCellEditor;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.ui.dialogs.PropertyPage;

public class SettingPropertyPage extends PropertyPage {
	private List<Setting> settings = new ArrayList();
	private List<Setting> settingsDefault;
	TableViewer viewer;

	private void loadSetting() {
		IProject project = (IProject) getElement().getAdapter(IProject.class);
		Activator.loadSetting(project.getName(), this.settings);
		this.settingsDefault = new ArrayList(this.settings);
	}

	private boolean saveSetting() {
		boolean result = false;
		IProject project = (IProject) getElement().getAdapter(IProject.class);
		File file = Activator.getDefault().getStateLocation().append(project.getName() + "_" + "setting.dat123456")
				.toFile();
		ObjectOutputStream output = null;
		try {
			for (Setting ss : this.settings) {
				if (ss.getConvertedEncoding().equals(ss.getCurrentEncoding())) {
					MessageDialog.openError(SettingPropertyPage.this.getShell(), "Error",
							ss.getSuffix() + " encoding is same as the encoding to convert!");
					return result;
				}
			}

			output = new ObjectOutputStream(new FileOutputStream(file));
			for (Setting ss : this.settings) {
				output.writeObject(ss);
			}
			output.writeObject(Activator.DUMP);
			output.flush();
			result = true;
		} catch (FileNotFoundException e) {
			Activator.logException(e);
			if (output != null) {
				try {
					output.close();
				} catch (IOException e1) {
					Activator.logException(e1);
				}
			}
		} catch (IOException e) {
			Activator.logException(e);
			if (output != null) {
				try {
					output.close();
				} catch (IOException e1) {
					Activator.logException(e1);
				}
			}
		} finally {
			if (output != null) {
				try {
					output.close();
				} catch (IOException e) {
					Activator.logException(e);
				}
			}
		}
		return result;
	}

	protected Control createContents(Composite parent) {
		loadSetting();
		Composite composite = new Composite(parent, 0);
		FormLayout layout = new FormLayout();
		layout.spacing = 10;
		layout.marginLeft = 10;
		layout.marginRight = 10;
		layout.marginTop = 10;
		composite.setLayout(layout);
		Label title = new Label(composite, 16777216);
		FormData title_data = new FormData();

		title_data.left = new FormAttachment(0);
		title_data.right = new FormAttachment(100);
		title_data.height = 30;
		title.setLayoutData(title_data);
		title.setText("Encoding predefined");

		Button add = new Button(composite, 0);
		add.setText("Add");
		Button remove = new Button(composite, 0);
		remove.setText("Remove");

		FormData add_data = new FormData();

		add_data.right = new FormAttachment(100);
		add_data.width = 120;
		add_data.top = new FormAttachment(title);

		FormData remove_data = new FormData();
		remove_data.right = new FormAttachment(100);
		remove_data.width = 120;
		remove_data.top = new FormAttachment(add);

		add.setLayoutData(add_data);
		remove.setLayoutData(remove_data);

		this.viewer = new TableViewer(composite, 65536);
		this.viewer.setContentProvider(new ArrayContentProvider());
		add.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				SettingPropertyPage.this.settings.add(Activator.newDefaultSetting());
				SettingPropertyPage.this.viewer.refresh();
			}
		});
		remove.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				IStructuredSelection selection = (IStructuredSelection) SettingPropertyPage.this.viewer.getSelection();
				if (!selection.isEmpty()) {
					SettingPropertyPage.this.settings.remove(selection.getFirstElement());
					SettingPropertyPage.this.viewer.refresh();
				}
			}
		});
		FormData viewer_data = new FormData();
		viewer_data.left = new FormAttachment(0);
		viewer_data.right = new FormAttachment(add);
		viewer_data.top = new FormAttachment(title);
		viewer_data.bottom = new FormAttachment(100);
		this.viewer.getControl().setLayoutData(viewer_data);
		this.viewer.getTable().setHeaderVisible(true);
		this.viewer.getTable().setLinesVisible(true);

		TableViewerColumn col_suffix = new TableViewerColumn(this.viewer, 0);
		col_suffix.getColumn().setText("Suffix");
		col_suffix.getColumn().setWidth(60);
		col_suffix.setLabelProvider(new ColumnLabelProvider() {
			public String getText(Object element) {
				return ((Setting) element).getSuffix();
			}
		});
		col_suffix.setEditingSupport(new EditingSupport(this.viewer) {
			private TextCellEditor editor = new TextCellEditor(SettingPropertyPage.this.viewer.getTable());

			protected boolean canEdit(Object element) {
				return true;
			}

			protected CellEditor getCellEditor(Object element) {
				return this.editor;
			}

			protected Object getValue(Object element) {
				return ((Setting) element).getSuffix();
			}

			protected void setValue(Object element, Object value) {
				Setting setting = (Setting) element;
				String suffix = (String) value;
				if (suffix.trim().length() == 0) {
					MessageDialog.openError(SettingPropertyPage.this.getShell(), "Error", "File suffix is empty!");
					return;
				}
				if (SettingPropertyPage.this.existType(setting, suffix)) {
					MessageDialog.openError(SettingPropertyPage.this.getShell(), "Error",
							"Setting for type '" + value + "' exists!");
				} else {
					setting.setSuffix(suffix);
					SettingPropertyPage.this.viewer.update(element, null);
				}
			}
		});
		TableViewerColumn col_current_encoding = new TableViewerColumn(this.viewer, 0);
		col_current_encoding.getColumn().setText("File Encoding");
		col_current_encoding.getColumn().setWidth(120);
		col_current_encoding.setLabelProvider(new ColumnLabelProvider() {
			public String getText(Object element) {
				return ((Setting) element).getCurrentEncoding();
			}
		});
		col_current_encoding.setEditingSupport(new EditingSupport(this.viewer) {
			private ComboBoxCellEditor encoding_editor = new ComboBoxCellEditor(
					SettingPropertyPage.this.viewer.getTable(),
					(String[]) Activator.FROM_ENCODINGS.toArray(new String[Activator.FROM_ENCODINGS.size()]), 8);

			protected boolean canEdit(Object element) {
				return true;
			}

			protected CellEditor getCellEditor(Object element) {
				return this.encoding_editor;
			}

			protected Object getValue(Object element) {
				return Integer.valueOf(Activator.FROM_ENCODINGS.indexOf(((Setting) element).getCurrentEncoding()));
			}

			protected void setValue(Object element, Object value) {
				Setting s = (Setting) element;
				String current_encoding = (String) Activator.FROM_ENCODINGS.get(((Integer) value).intValue());
//				if (s.getConvertedEncoding().equals(current_encoding)) {
					// MessageDialog.openError(SettingPropertyPage.this.getShell(),
					// "Error", "File encoding is same as the encoding to
					// convert!");
//				} else {
					s.setCurrentEncoding(current_encoding);
					SettingPropertyPage.this.viewer.update(element, null);
//				}
			}
		});
		TableViewerColumn col_be_encoding = new TableViewerColumn(this.viewer, 0);
		col_be_encoding.getColumn().setText("Convert To");
		col_be_encoding.getColumn().setWidth(120);
		col_be_encoding.setLabelProvider(new ColumnLabelProvider() {
			public String getText(Object element) {
				return ((Setting) element).getConvertedEncoding();
			}
		});
		col_be_encoding.setEditingSupport(new EditingSupport(this.viewer) {
			private ComboBoxCellEditor encoding_editor = new ComboBoxCellEditor(
					SettingPropertyPage.this.viewer.getTable(),
					(String[]) Activator.ENCODINGS.toArray(new String[Activator.ENCODINGS.size()]), 8);

			protected boolean canEdit(Object element) {
				return true;
			}

			protected CellEditor getCellEditor(Object element) {
				return this.encoding_editor;
			}

			protected Object getValue(Object element) {
				return Integer.valueOf(Activator.ENCODINGS.indexOf(((Setting) element).getConvertedEncoding()));
			}

			protected void setValue(Object element, Object value) {
				Setting s = (Setting) element;
				String converted = (String) Activator.ENCODINGS.get(((Integer) value).intValue());
//				if (s.getCurrentEncoding().equals(converted)) {
//					MessageDialog.openError(SettingPropertyPage.this.getShell(), "Error",
//							"Convert encoding  is same as file encoding!");
//				} else {
					s.setConvertedEncoding(converted);
					SettingPropertyPage.this.viewer.update(element, null);
//				}
			}
		});
		TableViewerColumn col_char_convert = new TableViewerColumn(this.viewer, 0);
		col_char_convert.getColumn().setText("Convert Char");
		col_char_convert.getColumn().setWidth(100);
		col_char_convert.setLabelProvider(new ColumnLabelProvider() {
			public String getText(Object element) {
				return String.valueOf(((Setting) element).isConvertCharacter());
			}
		});
		col_char_convert.setEditingSupport(new EditingSupport(this.viewer) {
			private CheckboxCellEditor bool_editor = new CheckboxCellEditor(SettingPropertyPage.this.viewer.getTable());

			protected boolean canEdit(Object element) {
				return true;
			}

			protected CellEditor getCellEditor(Object element) {
				return this.bool_editor;
			}

			protected Object getValue(Object element) {
				return Boolean.valueOf(((Setting) element).isConvertCharacter());
			}

			protected void setValue(Object element, Object value) {
				((Setting) element).setConvertCharacter(((Boolean) value).booleanValue());
				SettingPropertyPage.this.viewer.update(element, null);
			}
		});
		this.viewer.setInput(this.settings);

		return composite;
	}

	protected boolean existType(Setting setting, String suffix) {
		for (Setting s : this.settings) {
			if (s != setting) {
				if (s.getSuffix().equals(suffix)) {
					return true;
				}
			}
		}
		return false;
	}

	protected void performDefaults() {
		this.settings.clear();
		this.settings.addAll(this.settingsDefault);
		this.viewer.refresh();
	}

	public boolean performOk() {
		return saveSetting();
	}
}
